<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="default" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="任务名称" prop="jobName">
        <el-input  size="default"
          v-model="queryParams.jobName"
          placeholder="请输入任务名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="任务组名" prop="jobGroup">
        <el-select  size="default" v-model="queryParams.jobGroup" style="width:180px" placeholder="请选择任务组名" clearable>
          <el-option
            v-for="dict in sys_job_group"
            :key="dict.dataValue"
            :label="dict.dataName"
            :value="dict.dataValue"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="任务状态" prop="status">
        <el-select  size="default" v-model="queryParams.status"  style="width:180px"  placeholder="请选择任务状态" clearable>
          <el-option
            v-for="dict in sys_job_status"
            :key="dict.dataValue"
            :label="dict.dataName"
            :value="dict.dataValue"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button plain icon="Search"  type="primary"  size="default" @click="handleQuery">搜索</el-button>
        <el-button  plain icon="Refresh" size="default" @click="resetQuery(queryForm)">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="Edit"
          size="default"
          @click="handleAdd"
          v-if="userStore.hasPermission('monitor:job:add')"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="Edit"
          size="default"
          :disabled="single"
          @click="handleUpdate"
          v-if="userStore.hasPermission('monitor:job:edit')"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="Delete"
          size="default"
          :disabled="multiple"
          @click="handleDelete"
          v-if="userStore.hasPermission('monitor:job:remove')"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="Download"
          size="default"
          @click="handleExport"
          v-if="userStore.hasPermission('monitor:job:export')"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="Operation"
          size="default"
          @click="handleJobLog"
          v-if="userStore.hasPermission('monitor:job:query')"
        >日志</el-button>
      </el-col>
    </el-row>

    <el-table style="font-size: 16px;" v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="任务编号" width="100" align="center" prop="jobId" />
      <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
      <el-table-column label="任务组名" align="center" prop="jobGroup">
        <template  #default="scope">
          <div v-for="item in sys_job_group">
            <span  v-if="scope.row.jobGroup == item.dataValue">{{item.dataName}}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
      <el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
      <el-table-column label="状态" align="center">
        <template  #default="scope">
          <el-switch
            v-model="scope.row.status"
            active-value="0"
            inactive-value="1"
            @change="handleStatusChange(scope.row)"
          ></el-switch>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="auto">
        <template #default="scope">
          <el-button plain
            size="default"
            type="primary"
            icon="Edit"
            @click="handleUpdate(scope.row)"
            v-if="userStore.hasPermission('monitor:job:edit')"
          >修改</el-button>
          <el-button plain
              size="default"
              type="danger"
            icon="Delete"
            @click="handleDelete(scope.row)"
            v-if="userStore.hasPermission('monitor:job:remove')"
          >删除</el-button>
          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)"
                       v-if="userStore.hasPermission('monitor:job:changeStatus') && userStore.hasPermission('monitor:job:query')"
          >
            <el-button plain size="default"
                       type="info" icon="d-arrow-right">更多</el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="handleRun" icon="el-icon-caret-right"
                                  v-if="userStore.hasPermission('monitor:job:changeStatus')"
                >执行一次</el-dropdown-item>
                <el-dropdown-item command="handleView" icon="el-icon-view"
                                  v-if="userStore.hasPermission('monitor:job:query')"
                >任务详细</el-dropdown-item>
                <el-dropdown-item command="handleJobLog" icon="el-icon-s-operation"
                                  v-if="userStore.hasPermission('monitor:job:query')"
                >调度日志</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>
    <div class="el-pager">
      <el-pagination layout="total,sizes,prev, pager, next,jumper" :total="total"
                     :page-sizes="[10,20,30,40,50]" :pager-count="11"
                     size="default"  background  class="mt-4" :current-page="currentPage"
                     @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
    </div>
    <!-- 添加或修改定时任务对话框 -->
    <el-dialog :title="title" v-model="open"  width="800px" append-to-body>
      <el-form size="default" ref="ruleFormRef" :model="form" :rules="rules" label-width="120px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="任务名称" prop="jobName">
              <el-input v-model="form.jobName" placeholder="请输入任务名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="任务分组" prop="jobGroup">
              <el-select v-model="form.jobGroup" placeholder="请选择任务分组">
                <el-option
                  v-for="dict in sys_job_group"
                  :key="dict.dataValue"
                  :label="dict.dataName"
                  :value="dict.dataValue"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item prop="invokeTarget">
              <template #label>
                <el-tooltip placement="top">
                  <template #content>
                    Bean调用示例：ryTask.ryParams('ry')
                    <br />Class类调用示例：com.ruoyi.quartz.task.RyTask.ryParams('ry')
                    <br />参数说明：支持字符串，布尔类型，长整型，浮点型，整型
                    <i class="el-icon-question"></i>
                  </template>
                  调用方法
                </el-tooltip>
              </template>
              <el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="cron表达式" prop="cronExpression">
              <el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24" v-if="form.jobId !== undefined">
            <el-form-item label="状态">
              <el-radio-group v-model="form.status">
                <el-radio
                  v-for="dict in sys_job_status"
                  :key="dict.dataValue"
                  :label="dict.dataName"
                  :value="dict.dataValue"
                >{{dict.dataName}}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="执行策略" prop="misfirePolicy">
              <el-radio-group v-model="form.misfirePolicy" size="default">
                <el-radio-button label="1">立即执行</el-radio-button>
                <el-radio-button label="2">执行一次</el-radio-button>
                <el-radio-button label="3">放弃执行</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否并发" prop="concurrent">
              <el-radio-group v-model="form.concurrent" size="default">
                <el-radio-button label="0">允许</el-radio-button>
                <el-radio-button label="1">禁止</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button  size="default"  plain icon="Edit" type="primary" @click="submitForm(ruleFormRef)">确 定</el-button>
        <el-button  size="default"  plain @click="cancel()">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 任务日志详细 -->
    <el-dialog title="任务详细" v-model="openView" width="700px" append-to-body>
      <el-form  ref="form" :model="form" label-width="120px" size="default">
        <el-row>
          <el-col :span="12">
            <el-form-item label="任务编号：">{{ form.jobId }}</el-form-item>
            <el-form-item label="任务名称：">{{ form.jobName }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="任务分组：">
              <div v-for="item in sys_job_group">
                <span v-if="form.jobGroup == item.dataValue">{{item.dataName}}</span>
              </div>
            </el-form-item>
            <el-form-item label="创建时间：">{{ formatTimestamp(form.createTime) }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="cron表达式：">{{ form.cronExpression }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="下次执行时间：">{{ form.nextValidTime }}</el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="调用目标方法：">{{ form.invokeTarget }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="任务状态：">
              <div v-if="form.status == '0'">正常</div>
              <div v-else-if="form.status == '1'">暂停</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否并发：">
              <div v-if="form.concurrent == 0">允许</div>
              <div v-else-if="form.concurrent == 1">禁止</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="执行策略：">
              <div v-if="form.misfirePolicy == 0">默认策略</div>
              <div v-else-if="form.misfirePolicy == 1">立即执行</div>
              <div v-else-if="form.misfirePolicy == 2">执行一次</div>
              <div v-else-if="form.misfirePolicy == 3">放弃执行</div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="default" @click="openView = false">关 闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { page, info, remove, save, update, runJob, changeJobStatus } from "@/api/monitor/job";
import {useUserStore} from "@/stores/user.js";
import {onMounted, reactive, ref} from "vue";
import {ElMessage,ElMessageBox,ElTable } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus';
import {useRouteStore} from "@/stores/route.ts";
import {formatTimestamp} from "@/utils/date";
const userStore = useUserStore()
const useRoute = useRouteStore();
const router = useRoute.router;
const sys_job_group=userStore.getDictData('sys_job_group');
const sys_job_status=userStore.getDictData('sys_job_status');
const ids=ref([])
const single=ref(true)
const multiple=ref(true)
const queryForm=ref<FormInstance>();
onMounted(()=>{
  getList();
})
const currentPage = ref(1)
const handleSizeChange = (val: number) => {
  queryParams.value.page= val;
  getList();
}
const handleCurrentChange = (val: number) => {
  currentPage.value= val;
  queryParams.value.limit= val;
  getList();
}
const showSearch=ref(true)
const total=ref(0)
interface RuleForm {
  jobId:any,
  jobName: any
  jobGroup: any,
  invokeTarget:any,
  cronExpression:any,
  misfirePolicy:number,
  concurrent:number,
  status:string,
  nextValidTime:any
}
const ruleFormRef = ref<FormInstance>()
const form=reactive<RuleForm>({
  jobId: undefined,
  jobName: undefined,
  jobGroup: undefined,
  invokeTarget: undefined,
  cronExpression: undefined,
  misfirePolicy: 1,
  concurrent: 1,
  status: "0",
  nextValidTime:undefined
})
const openCron=ref(false)
const openView=ref(false)
const open=ref(false)
const title=ref('')
const jobList=ref([])
const queryParams=ref({
  page: 1,
  limit: 10,
  jobName: undefined,
  jobGroup: undefined,
  status: undefined
})
const rules = reactive<FormRules>({
  jobName: [
    { required: true, message: "任务名称不能为空", trigger: "blur" }
  ],
  invokeTarget: [
    { required: true, message: "调用目标字符串不能为空", trigger: "blur" }
  ],
  cronExpression: [
    { required: true, message: "cron执行表达式不能为空", trigger: "blur" }
  ]
})
const loading=ref(false)
/** 查询定时任务列表 */
const getList=()=> {
      loading.value = true;
      page(queryParams.value).then(response => {
        jobList.value = response.data.list;
        total.value = response.data.total;
        loading.value = false;
      });
}
// 取消按钮
const cancel=()=> {
      open.value = false;
}
/** 搜索按钮操作 */
const handleQuery=()=> {
      queryParams.value.page = 1;
      getList();
}
    /** 重置按钮操作 */
const resetQuery = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
  handleQuery();
}
// 多选框选中数据
const handleSelectionChange=(selection)=> {
      ids.value = selection.map(item => item.jobId);
      single.value = selection.length != 1;
      multiple.value = !selection.length;
}
    // 更多操作触发
const handleCommand=(command, row)=> {
  switch (command) {
    case "handleRun":
      handleRun(row);
      break;
    case "handleView":
      handleView(row);
      break;
    case "handleJobLog":
      handleJobLog(row);
      break;
    default:
      break;
  }
}
// 任务状态修改
const handleStatusChange=(row)=> {
      let text = row.status === "0" ? "启用" : "停用";
      ElMessageBox.confirm('确认要"' + text + '""' + row.jobName + '"任务吗？','提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      })
      .then(({ value }) => {
        changeJobStatus({jobId:row.jobId, status:row.status}).then((result) => {
          console.log(result);
          getList();
          ElMessage({
            type: 'success',
            message: text + "成功",
          })
        })
      })
      .catch((err) => {
        console.log("err"+err);
        row.status = row.status === "0" ? "1" : "0";
      })
}
    /* 立即执行一次 */
const handleRun=(row)=> {
  ElMessageBox.confirm('确认要立即执行一次"' + row.jobName + '"任务吗？','提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
  })
  .then(({ value }) => {
    const form={
      jobId:row.jobId,
      jobGroup:row.jobGroup,
    }
    runJob(form).then(response => {
      if (response.code == 200){
        getList();
        ElMessage({
          type: 'success',
          message: '执行成功',
        })
      }
    })

  })
  .catch(() => {
  })
}
/** 任务详细信息 */
const handleView=(row)=> {
      info(row.jobId).then(response => {
        form.jobId= response.data.jobId,
        form.jobName= response.data.jobName,
        form.jobGroup= response.data.jobGroup,
        form.invokeTarget= response.data.invokeTarget,
        form.cronExpression= response.data.cronExpression,
        form.misfirePolicy= response.data.misfirePolicy,
        form.concurrent= response.data.concurrent,
        form.status= response.data.status
        form.nextValidTime=response.data.nextValidTime
        openView.value = true;
      });
}
/** 确定后回传值 */
const crontabFill=(value)=> {
      form.cronExpression = value;
}
    /** 任务日志列表查询 */
const handleJobLog=(row)=> {
  const jobId = row.jobId || 0;
  router.push('/monitor/joblog/' + jobId)
}
/** 新增按钮操作 */
const handleAdd=()=>{
      open.value = true;
      title.value = "添加任务";
}
    /** 修改按钮操作 */
const handleUpdate=(row)=> {
  const jobId = row.jobId || ids.value;
  info(jobId).then(response => {
    form.jobId= response.data.jobId
    form.jobName= response.data.jobName
    form.jobGroup= response.data.jobGroup
    form.invokeTarget= response.data.invokeTarget
    form.cronExpression= response.data.cronExpression
    form.misfirePolicy= response.data.misfirePolicy
    form.concurrent= response.data.concurrent
    form.status= response.data.status
    form.nextValidTime=response.data.nextValidTime
    open.value = true;
    title.value = "修改任务";
  });
}
/** 提交按钮 */
const submitForm=(formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(async (valid, fields) => {
    if (valid) {
      console.log('submit!')
      if (form.jobId != undefined) {
        update(form).then(response => {
          ElMessage({
            type: 'success',
            message: '修改成功',
          })
          open.value = false;
          getList();
        });
      } else {
        save(form).then(response => {
          ElMessage({
            type: 'success',
            message: '新增成功',
          })
          open.value = false;
          getList();
        });
      }
    } else {
      console.log('error submit!', fields)
    }
  })
}
    /** 删除按钮操作 */
const handleDelete=(row)=> {
  const jobIds = row.jobId || this.ids;
  ElMessageBox.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项？','提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
  })
  .then(async ({ value }) =>  {
    await remove(jobIds)
    getList();
    ElMessage({
      type: 'success',
      message: '删除成功',
    })
    return true;
  })
  .catch(() => {
  })
}
/** 导出按钮操作 */
const handleExport=()=> {
  download('monitor/job/export', {
    ...queryParams.value
  }, `job_${new Date().getTime()}.xlsx`)
}
</script>
<style scoped>
.el-pager{
  padding: 2%;
  justify-content: right;
}
.dialog-footer{
  text-align: center;
}
</style>